"use strict";
cc._RF.push(module, '4f446PdEvFNPK+UEauIhfoP', 'VirtualJoystickController');
// scripts/game/VirtualJoystickController.ts

"use strict";
// Learn TypeScript:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/life-cycle-callbacks.html
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
var _a = cc._decorator, ccclass = _a.ccclass, property = _a.property;
/**
 * 虚拟摇杆控制器组件
 *
 * 功能特性：
 * - 背景圆形区域：196.6 × 196.6 像素
 * - 内部控制小球：75.2 × 75.2 像素
 * - 标准化坐标系统：X轴 -1 到 +1，Y轴 -1 到 +1
 * - 支持触摸和鼠标交互
 */
var VirtualJoystickController = /** @class */ (function (_super) {
    __extends(VirtualJoystickController, _super);
    function VirtualJoystickController() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.joystickBackground = null; // 摇杆背景圆形区域
        _this.joystickKnob = null; // 摇杆控制小球
        _this.callbackInterval = 0.016; // 约60FPS
        _this.enableClickToGenerate = true;
        _this.touchDetectionArea = null;
        // 摇杆规格常量
        _this.BACKGROUND_RADIUS = 196.6 / 2; // 背景半径
        _this.KNOB_SIZE = 75.2; // 小球尺寸
        _this.MAX_DISTANCE = _this.BACKGROUND_RADIUS - _this.KNOB_SIZE / 2; // 小球最大移动距离
        // 状态变量
        _this._isActive = false;
        // 默认初始化，防止外部在本组件 onLoad 之前调用 API 时出现空引用
        _this._currentInput = {
            x: 0,
            y: 0,
            force: 0,
            angle: 0,
            isActive: false,
        };
        _this._lastCallbackTime = 0;
        _this._isAtDefaultPosition = true; // 是否在默认位置
        _this._interactable = true; // 是否可交互
        // 当前占用摇杆的触点ID（多指时只接受第一个触点），null 表示无人占用
        _this._activeTouchId = null;
        // 回调函数
        _this._onJoystickMove = null;
        _this._onJoystickStart = null;
        _this._onJoystickEnd = null;
        return _this;
    }
    VirtualJoystickController.prototype.onLoad = function () {
        this.initializeJoystick();
    };
    VirtualJoystickController.prototype.start = function () {
        this.setupTouchEvents();
    };
    /**
     * 初始化摇杆
     */
    VirtualJoystickController.prototype.initializeJoystick = function () {
        // 初始化输入数据
        this._currentInput = {
            x: 0,
            y: 0,
            force: 0,
            angle: 0,
            isActive: false
        };
        // 保存摇杆的默认位置
        if (this.joystickBackground) {
            this._defaultPosition = this.joystickBackground.position.clone();
            this.joystickBackground.width = 196.6;
            this.joystickBackground.height = 196.6;
        }
        if (this.joystickKnob) {
            this.joystickKnob.width = this.KNOB_SIZE;
            this.joystickKnob.height = this.KNOB_SIZE;
            // 确保小球在中心位置
            this.joystickKnob.position = cc.v3(0, 0, 0);
        }
        this._isAtDefaultPosition = true;
    };
    /**
     * 设置触摸事件
     */
    VirtualJoystickController.prototype.setupTouchEvents = function () {
        if (this.enableClickToGenerate) {
            this.setupClickToGenerateMode();
        }
        else {
            this.setupFixedPositionMode();
        }
    };
    /**
     */
    VirtualJoystickController.prototype.setupClickToGenerateMode = function () {
        var detectionNode = this.touchDetectionArea || this.node.parent || cc.director.getScene();
        if (!detectionNode) {
            cc.warn("VirtualJoystickController: 无法找到触摸检测区域");
            return;
        }
        // 在检测区域上监听触摸事件
        detectionNode.on(cc.Node.EventType.TOUCH_START, this.onScreenTouchStart, this);
        detectionNode.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        detectionNode.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
        detectionNode.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
    };
    /**
     * 设置固定位置模式的触摸事件
     */
    VirtualJoystickController.prototype.setupFixedPositionMode = function () {
        if (!this.joystickBackground) {
            cc.warn("VirtualJoystickController: joystickBackground 未设置");
            return;
        }
        // 在摇杆背景上监听触摸事件
        this.joystickBackground.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.joystickBackground.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.joystickBackground.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.joystickBackground.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
    };
    /**
     * 屏幕触摸开始事件（点击生成模式）
     */
    VirtualJoystickController.prototype.onScreenTouchStart = function (event) {
        if (!this._interactable)
            return;
        var id = event.getID();
        // 若已有其他手指占用，则忽略本次触摸
        if (this._activeTouchId !== null && this._activeTouchId !== id) {
            return;
        }
        // 认领触点
        if (this._activeTouchId === null)
            this._activeTouchId = id;
        // 将摇杆移动到点击位置
        var touchLocation = event.getLocation();
        var worldPos = this.node.parent.convertToNodeSpaceAR(touchLocation);
        // 移动摇杆到点击位置
        this.joystickBackground.position = cc.v3(worldPos.x, worldPos.y, 0);
        this._isAtDefaultPosition = false;
        // 激活摇杆
        this._isActive = true;
        this._currentInput.isActive = true;
        // 重置小球位置到摇杆中心
        this.joystickKnob.position = cc.v3(0, 0, 0);
        if (this._onJoystickStart) {
            this._onJoystickStart(this.getCurrentInputData());
        }
    };
    /**
     * 触摸开始事件（固定位置模式）
     */
    VirtualJoystickController.prototype.onTouchStart = function (event) {
        if (!this._interactable)
            return;
        var id = event.getID();
        // 若已有其他手指占用，则忽略
        if (this._activeTouchId !== null && this._activeTouchId !== id) {
            return;
        }
        // 认领触点
        if (this._activeTouchId === null)
            this._activeTouchId = id;
        this._isActive = true;
        this._currentInput.isActive = true;
        var touchPos = this.getTouchPosition(event);
        this.updateJoystickPosition(touchPos);
        if (this._onJoystickStart) {
            this._onJoystickStart(this.getCurrentInputData());
        }
    };
    /**
     * 触摸移动事件
     */
    VirtualJoystickController.prototype.onTouchMove = function (event) {
        if (!this._isActive || !this._interactable)
            return;
        // 仅处理占用该摇杆的触点
        if (this._activeTouchId !== null && event.getID() !== this._activeTouchId) {
            return;
        }
        var touchPos = this.getTouchPosition(event);
        this.updateJoystickPosition(touchPos);
    };
    /**
     * 触摸结束事件
     */
    VirtualJoystickController.prototype.onTouchEnd = function (_event) {
        if (!this._interactable && !this._isActive)
            return;
        // 仅在结束的是占用触点时才真正结束
        if (this._activeTouchId !== null && _event.getID() !== this._activeTouchId) {
            return;
        }
        this._isActive = false;
        this._currentInput.isActive = false;
        // 重置摇杆位置
        this.resetJoystickPosition();
        // 如果是点击生成模式，将摇杆移回默认位置
        if (this.enableClickToGenerate && !this._isAtDefaultPosition) {
            this.moveJoystickToDefaultPosition();
        }
        if (this._onJoystickEnd) {
            this._onJoystickEnd(this.getCurrentInputData());
        }
        // 释放占用
        this._activeTouchId = null;
    };
    /**
     * 获取触摸位置（相对于摇杆背景）
     */
    VirtualJoystickController.prototype.getTouchPosition = function (event) {
        var touchLocation = event.getLocation();
        return this.joystickBackground.convertToNodeSpaceAR(touchLocation);
    };
    /**
     * 更新摇杆位置和输入数据
     */
    VirtualJoystickController.prototype.updateJoystickPosition = function (localPos) {
        // 计算距离中心的偏移
        var distance = localPos.mag();
        // 限制在最大距离内
        var clampedDistance = Math.min(distance, this.MAX_DISTANCE);
        // 计算标准化方向
        var normalizedX = 0;
        var normalizedY = 0;
        var angle = 0;
        if (distance > 0) {
            var direction = localPos.normalize();
            normalizedX = direction.x;
            normalizedY = direction.y;
            angle = Math.atan2(direction.y, direction.x);
            // 更新小球位置
            var clampedPos = direction.mul(clampedDistance);
            this.joystickKnob.position = cc.v3(clampedPos.x, clampedPos.y, 0);
        }
        // 更新输入数据
        this._currentInput.x = normalizedX * (clampedDistance / this.MAX_DISTANCE);
        this._currentInput.y = normalizedY * (clampedDistance / this.MAX_DISTANCE);
        this._currentInput.force = clampedDistance / this.MAX_DISTANCE;
        this._currentInput.angle = angle;
        // 触发移动回调
        this.triggerMoveCallback();
    };
    /**
     * 重置摇杆位置（只重置小球位置）
     */
    VirtualJoystickController.prototype.resetJoystickPosition = function () {
        if (this.joystickKnob) {
            this.joystickKnob.position = cc.v3(0, 0, 0);
        }
        // 重置输入数据
        this._currentInput.x = 0;
        this._currentInput.y = 0;
        this._currentInput.force = 0;
        this._currentInput.angle = 0;
    };
    /**
     * 将摇杆移动到默认位置
     */
    VirtualJoystickController.prototype.moveJoystickToDefaultPosition = function () {
        if (this.joystickBackground && this._defaultPosition) {
            this.joystickBackground.position = this._defaultPosition.clone();
            this._isAtDefaultPosition = true;
        }
    };
    /**
     * 触发移动回调
     */
    VirtualJoystickController.prototype.triggerMoveCallback = function () {
        if (!this._onJoystickMove)
            return;
        var currentTime = Date.now() / 1000;
        if (this.callbackInterval <= 0 || currentTime - this._lastCallbackTime >= this.callbackInterval) {
            this._onJoystickMove(this.getCurrentInputData());
            this._lastCallbackTime = currentTime;
        }
    };
    /**
     * 获取当前输入数据的副本
     */
    VirtualJoystickController.prototype.getCurrentInputData = function () {
        return {
            x: this._currentInput.x,
            y: this._currentInput.y,
            force: this._currentInput.force,
            angle: this._currentInput.angle,
            isActive: this._currentInput.isActive
        };
    };
    // ========== 公共API ==========
    /**
     * 设置摇杆移动回调
     */
    VirtualJoystickController.prototype.setOnJoystickMove = function (callback) {
        this._onJoystickMove = callback;
    };
    /**
     * 设置摇杆开始回调
     */
    VirtualJoystickController.prototype.setOnJoystickStart = function (callback) {
        this._onJoystickStart = callback;
    };
    /**
     * 设置摇杆结束回调
     */
    VirtualJoystickController.prototype.setOnJoystickEnd = function (callback) {
        this._onJoystickEnd = callback;
    };
    /**
     * 获取当前摇杆输入数据
     */
    VirtualJoystickController.prototype.getInputData = function () {
        return this.getCurrentInputData();
    };
    /**
     * 获取移动方向向量（已标准化）
     */
    VirtualJoystickController.prototype.getDirection = function () {
        return new cc.Vec2(this._currentInput.x, this._currentInput.y);
    };
    /**
     * 获取移动速度（考虑力度）
     */
    VirtualJoystickController.prototype.getVelocity = function (maxSpeed) {
        if (maxSpeed === void 0) { maxSpeed = 1; }
        var direction = this.getDirection();
        return direction.mul(this._currentInput.force * maxSpeed);
    };
    /**
     * 是否正在被操作
     */
    VirtualJoystickController.prototype.isActive = function () {
        return this._isActive;
    };
    /**
     * 手动将摇杆移动到默认位置
     */
    VirtualJoystickController.prototype.moveToDefaultPosition = function () {
        this.moveJoystickToDefaultPosition();
    };
    /**
     * 设置是否可交互
     */
    VirtualJoystickController.prototype.setInteractable = function (enabled) {
        this._interactable = enabled;
        if (!enabled) {
            // 禁用时重置输入与位置
            this._isActive = false;
            // 惰性初始化，防止在 onLoad 之前被外部调用导致 _currentInput 为空
            if (!this._currentInput) {
                this._currentInput = { x: 0, y: 0, force: 0, angle: 0, isActive: false };
            }
            this._currentInput.isActive = false;
            // 释放占用，避免残留触点控制
            this._activeTouchId = null;
            this.resetJoystickPosition();
            if (this.enableClickToGenerate && !this._isAtDefaultPosition) {
                this.moveJoystickToDefaultPosition();
            }
            // 视觉上隐藏摇杆，避免用户误以为还能拖动
            if (this.joystickBackground)
                this.joystickBackground.active = false;
            if (this.joystickKnob)
                this.joystickKnob.active = false;
        }
        else {
            // 恢复可交互时，显示摇杆
            if (this.joystickBackground)
                this.joystickBackground.active = true;
            if (this.joystickKnob)
                this.joystickKnob.active = true;
        }
    };
    /**
     * 当前是否可交互
     */
    VirtualJoystickController.prototype.isInteractable = function () {
        return this._interactable;
    };
    /**
     * 设置摇杆的默认位置
     */
    VirtualJoystickController.prototype.setDefaultPosition = function (position) {
        this._defaultPosition = position.clone();
        if (this._isAtDefaultPosition) {
            this.joystickBackground.position = this._defaultPosition.clone();
        }
    };
    /**
     * 获取摇杆的默认位置
     */
    VirtualJoystickController.prototype.getDefaultPosition = function () {
        return this._defaultPosition ? this._defaultPosition.clone() : cc.v3(0, 0, 0);
    };
    /**
     * 摇杆是否在默认位置
     */
    VirtualJoystickController.prototype.isAtDefaultPosition = function () {
        return this._isAtDefaultPosition;
    };
    VirtualJoystickController.prototype.onDestroy = function () {
        // 清理事件监听
        if (this.enableClickToGenerate) {
            var detectionNode = this.touchDetectionArea || this.node.parent || cc.director.getScene();
            if (detectionNode) {
                detectionNode.off(cc.Node.EventType.TOUCH_START, this.onScreenTouchStart, this);
                detectionNode.off(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
                detectionNode.off(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
                detectionNode.off(cc.Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
            }
        }
        else {
            if (this.joystickBackground) {
                this.joystickBackground.off(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
                this.joystickBackground.off(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
                this.joystickBackground.off(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
                this.joystickBackground.off(cc.Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
            }
        }
    };
    __decorate([
        property(cc.Node)
    ], VirtualJoystickController.prototype, "joystickBackground", void 0);
    __decorate([
        property(cc.Node)
    ], VirtualJoystickController.prototype, "joystickKnob", void 0);
    __decorate([
        property({
            displayName: "摇杆回调间隔(秒)",
            tooltip: "摇杆数据回调的时间间隔，0表示每帧都回调"
        })
    ], VirtualJoystickController.prototype, "callbackInterval", void 0);
    __decorate([
        property({
            displayName: "点击生成摇杆",
            tooltip: "启用后，点击屏幕任意位置生成摇杆，松开后回到默认位置"
        })
    ], VirtualJoystickController.prototype, "enableClickToGenerate", void 0);
    __decorate([
        property({
            displayName: "检测区域",
            tooltip: "用于检测点击的区域节点，通常是整个屏幕或游戏区域"
        })
    ], VirtualJoystickController.prototype, "touchDetectionArea", void 0);
    VirtualJoystickController = __decorate([
        ccclass
    ], VirtualJoystickController);
    return VirtualJoystickController;
}(cc.Component));
exports.default = VirtualJoystickController;

cc._RF.pop();